package com.bamboo.pistorage.provider.file;

import cn.hutool.core.io.FileUtil;
import com.bamboo.core.enums.code.CodeCommonEnum;
import com.bamboo.core.exceptions.BambooException;
import com.bamboo.model.enums.FileTypeEnum;
import com.bamboo.pistorage.provider.IFileCheckerProvider;

import java.io.File;
import java.util.List;

/**
 * @author chenzh
 * @description 检测文件是否满足上传条件
 * @date 2025/4/3 上午10:20
 */
public abstract class AbstractFileCheckerProvider implements IFileCheckerProvider {

    @Override
    public final void check(File file) {
        // 检测文件是否为空
        if (file == null) {
            throw new BambooException(CodeCommonEnum.INVALID_ARG, "上传的文件不能为空");
        }
        // 检测文件是否存在
        if (!file.exists()) {
            throw new BambooException(CodeCommonEnum.INVALID_ARG, "上传的文件不存在");
        }
        if (file.isDirectory()) {
            throw new BambooException(CodeCommonEnum.INVALID_ARG, "上传的文件不能是目录");
        }
        // 检测文件大小是否超过限制
        FileTypeEnum suffix = FileTypeEnum.getEnumBySuffix(FileUtil.getSuffix(file));
        long maxFileSize = this.getMaxFileSize(suffix);
        if (file.length() > maxFileSize) {
            throw new BambooException(
                    CodeCommonEnum.INVALID_ARG, String.format("上传的文件大小不能超过%dMB", maxFileSize / 1024 / 1024)
            );
        }
        // 检测文件类型是否符合要求
        if (!this.getAllowFileTypes().contains(FileUtil.getSuffix(file))) {
            throw new BambooException(CodeCommonEnum.INVALID_ARG, String.format("不支持上传类型<%s>的文件", suffix));
        }
    }

    @Override
    public List<String> getAllowFileTypes() {
        return FileTypeEnum.getAllTypes();
    }

    @Override
    public long getMaxFileSize(FileTypeEnum type) {
        switch (type) {
            case DOC:
                // 文件支持5MB以下
                return 5 * 1024 * 1024;
            case IMAGE:
                // 图片支持2MB以下
                return 2 * 1024 * 1024;
            case VIDEO:
                // 视频支持5MB以下
                return 5 * 1024 * 1024;
            case AUDIO:
                // 音频支持5MB以下
                return 5 * 1024 * 1024;
            case OTHER:
            default:
                // 其他文件支持5MB以下
                return 5 * 1024 * 1024;
        }
    }
}
